#include "connectionmanager.h"
#include <QStandardPaths>
#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QSqlDatabase>
#include <QUuid>
#include <QApplication>

ConnectionManager::ConnectionManager(QObject *parent)
    : QObject(parent)
{
    loadConnections();
}

bool ConnectionManager::saveConnection(const QString &name, const ConnectionConfig &config)
{
    if (name.isEmpty()) {
        return false;
    }
    
    m_connections[name] = config;
    return saveConnections();
}

bool ConnectionManager::removeConnection(const QString &name)
{
    if (!connectionExists(name)) {
        return false;
    }
    
    m_connections.remove(name);
    return saveConnections();
}

ConnectionConfig ConnectionManager::getConnection(const QString &name) const
{
    return m_connections.value(name, ConnectionConfig());
}

QStringList ConnectionManager::getConnectionNames() const
{
    return m_connections.keys();
}

bool ConnectionManager::connectionExists(const QString &name) const
{
    return m_connections.contains(name);
}

QSqlDatabase ConnectionManager::createDatabaseConnection(const QString &name) const
{
    if (!connectionExists(name)) {
        return QSqlDatabase();
    }
    
    ConnectionConfig config = getConnection(name);
    return createDatabaseConnection(config);
}

QSqlDatabase ConnectionManager::createDatabaseConnection(const ConnectionConfig &config) const
{
    QString connectionName = QUuid::createUuid().toString();
    QSqlDatabase db = QSqlDatabase::addDatabase(config.driver, connectionName);
    
    db.setHostName(config.host);
    db.setDatabaseName(config.database);
    db.setUserName(config.username);
    db.setPassword(config.password);
    if (config.port > 0) {
        db.setPort(config.port);
    }
    
    return db;
}

bool ConnectionManager::loadConnections()
{
    QString configFile = getConfigFilePath();
    QFile file(configFile);
    
    if (!file.exists() || !file.open(QIODevice::ReadOnly)) {
        return false;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (!doc.isArray()) {
        return false;
    }
    
    QJsonArray array = doc.array();
    for (const QJsonValue &value : array) {
        if (!value.isObject()) {
            continue;
        }
        
        QJsonObject obj = value.toObject();
        ConnectionConfig config;
        config.name = obj["name"].toString();
        config.driver = obj["driver"].toString();
        config.host = obj["host"].toString();
        config.database = obj["database"].toString();
        config.username = obj["username"].toString();
        config.password = obj["password"].toString();
        config.port = obj["port"].toInt();
        
        if (!config.name.isEmpty()) {
            m_connections[config.name] = config;
        }
    }
    
    return true;
}

bool ConnectionManager::saveConnections()
{
    QString configFile = getConfigFilePath();
    QFile file(configFile);
    
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }
    
    QJsonArray array;
    for (const QString &name : m_connections.keys()) {
        ConnectionConfig config = m_connections[name];
        QJsonObject obj;
        obj["name"] = config.name;
        obj["driver"] = config.driver;
        obj["host"] = config.host;
        obj["database"] = config.database;
        obj["username"] = config.username;
        obj["password"] = config.password;
        obj["port"] = config.port;
        
        array.append(obj);
    }
    
    QJsonDocument doc(array);
    file.write(doc.toJson());
    file.close();
    
    return true;
}

QString ConnectionManager::getConfigFilePath() const
{
    QString configPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    QDir dir(configPath);
    if (!dir.exists()) {
        dir.mkpath(".");
    }
    
    return dir.filePath("connections.json");
}